package com.example.demo.service.impl;

import com.aliyun.opensearch.sdk.generated.commons.OpenSearchClientException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchException;
import com.example.demo.constant.RedisKey;
import com.example.demo.enumeration.Campus;
import com.example.demo.enumeration.ItemStatus;
import com.example.demo.mapper.*;
import com.example.demo.pojo.entity.Item;
import com.example.demo.pojo.properties.AliyunOpenSearchProperties;
import com.example.demo.pojo.vo.*;
import com.example.demo.service.AdminService;
import com.example.demo.utils.AliyunOpenSearchUtil;
import com.example.demo.utils.JwtUtil;
import com.example.demo.utils.ThreadLocalUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private ItemImageMapper itemImageMapper;
    @Autowired
    private CampusMapper campusMapper;
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate; //报错信息错误，无影响

    /* 阿里云OpenSearch续费太贵，暂时停用
    @Autowired
    private AliyunOpenSearchProperties aliyunOpenSearchProperties;
    */

    @Override
    public Long selectIdByUsername(String username) {
        return adminMapper.selectIdByUsername(username);
    }

    @Override
    public boolean checkPassword(String username, String password) {
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        String pwd = adminMapper.selectPasswordByUsername(username);

        return password.equals(pwd);
    }

    @Override
    public String generateAdminToken(Long id, String username) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", id);
        claims.put("username", username);

        String token = JwtUtil.getToken(claims);

        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.set(RedisKey.ADMIN_PREFIX + id, token, 7, TimeUnit.DAYS);

        return token;
    }

    @Override
    public Long getCurrentAdminId() {
        Map<String, Object> map = ThreadLocalUtil.get();
        Long id = Long.parseLong(map.get("id").toString());

        return id;
    }

    @Override
    public void deleteToken(Long id) {
        stringRedisTemplate.opsForValue().getOperations().delete(RedisKey.ADMIN_PREFIX + id);
    }

    @Override
    public PageVO getPendingItemList(int page) {
        PageHelper.startPage(page, 16);

        Page<ItemListVO> data = itemMapper.selectPendingItemList();

        List<ItemListVO> list = data.getResult();

        for (int i = 0; i < list.size(); i++) {
            ItemListVO itemListVO = list.get(i);

            Long itemId = itemListVO.getId();
            List<Campus> campuses = campusMapper.selectCampusByItemId(itemId);

            itemListVO.setCampuses(campuses);
        }

        PageVO pageVO = new PageVO(data.getTotal(), list);

        return pageVO;
    }

    @Override
    public ItemDetailVO getItemDetail(Long itemId) {
        Item item = itemMapper.selectItemById(itemId);

        if (item == null) {
            return null;
        }

        ItemDetailVO itemDetailVO = new ItemDetailVO();

        BeanUtils.copyProperties(item, itemDetailVO);

        List<String> images = itemImageMapper.selectImageUrlByItemId(itemId);
        itemDetailVO.setImages(images);

        List<Campus> campuses = campusMapper.selectCampusByItemId(itemId);
        itemDetailVO.setCampuses(campuses);

        return itemDetailVO;
    }

    @Override
    @Transactional
    public boolean updateItemStatus(Long itemId, ItemStatus status) {
        boolean statusResult = itemMapper.updateStatusById(itemId, status);
        if (!statusResult) {
            return false;
        }

        /* 在阿里云OpenSearch更改数据，OpenSearch续费太贵，暂时停用
        try {
            boolean result = AliyunOpenSearchUtil.updateItemStatus(aliyunOpenSearchProperties, itemId, status);
            if (!result) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return false;
            }
        } catch (OpenSearchClientException | OpenSearchException exception) {
            exception.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        */

        return true;
    }

    @Override
    public PageVO getItemReportList(int page) {
        PageHelper.startPage(page, 16);

        Page<ItemReportVO> data = reportMapper.selectItemReport();

        PageVO pageVO = new PageVO(data.getTotal(), data.getResult());

        return pageVO;
    }

    @Override
    public PageVO getCommentReportList(int page) {
        PageHelper.startPage(page, 16);

        Page<CommentReportVO> data = reportMapper.selectCommentReport();

        PageVO pageVO = new PageVO(data.getTotal(), data.getResult());

        return pageVO;
    }

    @Override
    public List<Long> selectReportIdListByItemId(Long itemId) {
        return reportMapper.selectIdListByItemId(itemId);
    }

    @Override
    public List<Long> selectReportIdListByCommentId(Long commentId) {
        return reportMapper.selectIdListByCommentId(commentId);
    }

    @Override
    public boolean deleteReportByItemId(Long itemId) {
        return reportMapper.deleteReportByItemId(itemId);
    }

    @Override
    public boolean deleteReportByCommentId(Long commentId) {
        return reportMapper.deleteReportByCommentId(commentId);
    }
}
